package com.gitee.melin.bee.util;

import static java.util.regex.Pattern.CASE_INSENSITIVE;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;

public class PasswordUtils {

    private static final String PASSWORD_MASK = "******";

    private static final String PASSWORD_CONTAINING_REGEX_1 =
            "(.*)(password|secretAccessKey|secretKey)[\\'\\\"]?[\\s]*[=:][\\s]*[\\'\\\"]?(.*?)[\\'\\\"]+?";

    private static final String PASSWORD_CONTAINING_REGEX_2 =
            "(.*)(password|secretAccessKey|secretKey)[\\'\\\"]?[\\s]*[=:][\\s]*(.*)";

    private static final Pattern PASSWORD_CONTAINING_PATTERN_1 =
            Pattern.compile(PASSWORD_CONTAINING_REGEX_1, CASE_INSENSITIVE);

    private static final Pattern PASSWORD_CONTAINING_PATTERN_2 =
            Pattern.compile(PASSWORD_CONTAINING_REGEX_2, CASE_INSENSITIVE);

    public static String mask(String value) {
        if (value == null || value.isEmpty()) {
            return value;
        }

        String masked = maskPasswordFragments(PASSWORD_CONTAINING_PATTERN_1, value);
        if (masked.equals(value)) {
            masked = maskPasswordFragments(PASSWORD_CONTAINING_PATTERN_2, value);
        }

        return masked;
    }

    private static String maskPasswordFragments(Pattern pattern, String value) {
        StringBuilder maskedBuilder = new StringBuilder();
        Matcher matcher = pattern.matcher(value);

        int start = 0, end;
        while (matcher.find()) {
            end = matcher.start();

            maskedBuilder.append(value.substring(start, end));

            String group = matcher.group(0);
            String password = matcher.group(3);
            group = StringUtils.replace(group, password, PASSWORD_MASK);
            maskedBuilder.append(group);

            start = matcher.end();
        }

        maskedBuilder.append(value.substring(start));

        if (maskedBuilder.length() == 0) {
            return value;
        }
        return maskedBuilder.toString();
    }

    /**
     * 验证密码是否包含至少一个大写字母、一个小写字母和一个数字。
     *
     * @param password 待验证的密码字符串
     * @return 如果密码满足所有条件则返回 true，否则返回 false
     */
    public static boolean validatePassword(String password) {
        // 正则表达式解释：
        // ^                 - 字符串的开始
        // (?=.*[A-Z])       - 正向先行断言：确保字符串中至少包含一个大写字母 (A-Z)
        // (?=.*[a-z])       - 正向先行断言：确保字符串中至少包含一个小写字母 (a-z)
        // (?=.*\\d)         - 正向先行断言：确保字符串中至少包含一个数字 (0-9)
        // .*                - 匹配任何字符（除了行终止符），零次或多次。
        // $                 - 字符串的结束
        //
        // 注意：这个正则表达式只检查了必须包含大写、小写和数字，
        // 没有对密码的最小/最大长度或是否包含特殊字符做限制。
        String regex = "^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d).*$";

        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(password);

        return matcher.matches();
    }
}
